using System.Linq;
using Sessionizer.Core;
using Sessionizer.Samples.Model;
using Sessionizer.Samples.Model.Imp;

namespace Sessionizer.Samples.Sessionized.TopBuilder
{
    /// <summary>
    /// This factory will be used to construct instance upon session.Get[ITop]
    /// Implements ranking.
    /// </summary>
    internal sealed class SessionsTopFactory : ISessionsFactory<ITop>
    {
        private readonly IRankAggregator _rankAggregator;
        private readonly ISessions<ITeamCollection> _teams;
        private readonly ISessions<ITopCount> _topCount;

        /// <summary>
        /// Injects components and session data
        /// </summary>
        /// <param name="rankAggregator">Composite over rankers. Internal component.</param>
        /// <param name="teams">Wrapper around session's data containing corresponding ITeamCollection instance.</param>
        /// <param name="topCount">Wrapper around session's data containing corresponding ITopCount instance.</param>
        public SessionsTopFactory(
            IRankAggregator rankAggregator,
            ISessions<ITeamCollection> teams,
            ISessions<ITopCount> topCount
            )
        {
            _rankAggregator = rankAggregator;
            _teams = teams;
            _topCount = topCount;
        }

        public ITop Create()
        {
            return
                new Top(
                    _teams.Instance.Select(team => new {Team = team, Rank = _rankAggregator.GetRank(team)})
                          .OrderBy(rec => rec.Rank)
                          .Take(_topCount.Instance.Count)
                          .Select((rec, pos) => new TopRecord(rec.Team, pos + 1, rec.Rank)).ToList());
        }
    }
}